#include "mybluetooth.h"
#include "esp_log.h"


uint8_t adv_config_done = 0;// 用于标记广告数据配置是否完成，初始值为 0

prepare_type_env_t prepare_write_env;// 用于保存写入请求相关的环境数据
// 如果启用了 CONFIG_SET_RAW_ADV_DATA 配置，定义原始广告数据
uint8_t raw_adv_data[] = {
        /* flags */
        0x02, 0x01, 0x06, // 广告标志，0x06 表示支持 LE 和 BR/EDR 并行工作
        /* tx power*/
        0x02, 0x0a, 0xeb, // 传输功率，0xEB 表示大约 -21dBm
        /* service uuid */
        0x03, 0x03, 0xFF, 0x00, // 服务 UUID，0xFF00 是一个自定义的服务 UUID
        /* device name */
        0x0f, 0x09, 'E', 'S', 'P', '_', 'G', 'A', 'T', 'T', 'S', '_', 'D','E', 'M', 'O' //在这里修改名称，这一行第一位0x0f表示名称长度，修改时要同步修改
};
uint8_t raw_scan_rsp_data[] = {
        /* flags */
        0x02, 0x01, 0x06, // 广告标志
        /* tx power */
        0x02, 0x0a, 0xeb, // 传输功率
        /* service uuid */
        0x03, 0x03, 0xFF,0x00 // 服务 UUID
};




static const uint8_t BLE_EXT_ADV_HANDLE = 0;

static esp_ble_gap_ext_adv_params_t ext_adv_params = {
    .type           = ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND,
    .interval_min   = 0x20, // 32 * 0.625 ms = 20 ms
    .interval_max   = 0x40, // 64 * 0.625 ms = 40 ms
    .channel_map    = ADV_CHNL_ALL,
    .own_addr_type  = BLE_ADDR_TYPE_PUBLIC,
    .peer_addr_type = BLE_ADDR_TYPE_PUBLIC,
    .peer_addr      = {0},
    .filter_policy  = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
    .tx_power       = EXT_ADV_TX_PWR_NO_PREFERENCE,
    .primary_phy    = ESP_BLE_GAP_PHY_1M,
    .max_skip       = 0,
    .secondary_phy  = ESP_BLE_GAP_PHY_1M,
    .sid            = 0,
    .scan_req_notif = false,
};

static const esp_ble_gap_ext_adv_t ext_adv_cfg = {
    .instance   = BLE_EXT_ADV_HANDLE,
    .duration   = 0,
    .max_events = 0,
};

static void start_ext_advertising(void)
{
    if (adv_config_done != 0) {
        return;
    }

    esp_err_t ret = esp_ble_gap_ext_adv_start(1, &ext_adv_cfg);
    if (ret != ESP_OK) {
        ESP_LOGE(BLE_TAG, "ext adv start failed: %s", esp_err_to_name(ret));
    }
}

struct gatts_profile_inst heart_rate_profile_tab[PROFILE_NUM] = {
    [PROFILE_APP_IDX] = {
        .gatts_cb = gatts_profile_event_handler, // GATT 服务事件处理回调函数
        .gatts_if = ESP_GATT_IF_NONE,       // 未获取 gatt_if，初始值为 ESP_GATT_IF_NONE
    },
};


/* Service */
const uint16_t GATTS_SERVICE_UUID_TEST      = 0x00FF; // 服务 UUID
const uint16_t GATTS_CHAR_UUID_TEST_A       = 0xFF01; // 特征 UUID


const uint16_t primary_service_uuid         = ESP_GATT_UUID_PRI_SERVICE;        // 服务声明 UUID
const uint16_t character_declaration_uuid   = ESP_GATT_UUID_CHAR_DECLARE;       // 特征声明 UUID
const uint16_t character_client_config_uuid = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; // 客户端配置描述符 UUID

const uint8_t char_prop_read_write_notify   = ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_NOTIFY; // 特征属性设置，支持读、写和通知功能
const uint8_t heart_measurement_ccc[2]      = {0x00, 0x00};// 客户端配置描述符初始值，表示通知未启用
const uint8_t char_value[10]                 = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // 

bool connected=0;


const esp_gatts_attr_db_t gatt_db[HRS_IDX_NB] =
{
    // 服务声明
    [IDX_SVC]        =
    {{ESP_GATT_AUTO_RSP},  // 响应类型：自动响应
     {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ,
      sizeof(uint16_t), sizeof(GATTS_SERVICE_UUID_TEST), (uint8_t *)&GATTS_SERVICE_UUID_TEST}},
    // 这个属性描述了一个服务，服务的 UUID 为 `GATTS_SERVICE_UUID_TEST`
    // 属性权限为 `ESP_GATT_PERM_READ`，即此服务可以被读取
    // 服务的大小由 `GATTS_SERVICE_UUID_TEST` 的大小决定

    /* 特征声明 */
    [IDX_CHAR_A]     =
    {{ESP_GATT_AUTO_RSP},  // 响应类型：自动响应
     {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
      CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write_notify}},
    // 这个属性描述了一个特征声明，特征的 UUID 为 `character_declaration_uuid`
    // 特征的权限为 `ESP_GATT_PERM_READ`，即可以读取该特征的声明
    // `CHAR_DECLARATION_SIZE` 表示特征声明的大小，通常是 1 字节

    /* 特征值 */
    [IDX_CHAR_VAL_A] =
    {{ESP_GATT_AUTO_RSP},  // 响应类型：自动响应
     {ESP_UUID_LEN_16, (uint8_t *)&GATTS_CHAR_UUID_TEST_A, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
      GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(char_value), (uint8_t *)char_value}},
    // 这个属性描述了特征的值，特征值的 UUID 为 `GATTS_CHAR_UUID_TEST_A`
    // 特征值权限为 `ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE`，即既可以读取也可以写入
    // `GATTS_DEMO_CHAR_VAL_LEN_MAX` 表示特征值的最大长度，`char_value` 存储特征的当前值

    /* 客户端特征配置描述符 */
    [IDX_CHAR_CFG_A]  =
    {{ESP_GATT_AUTO_RSP},  // 响应类型：自动响应
     {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
      sizeof(uint16_t), sizeof(heart_measurement_ccc), (uint8_t *)heart_measurement_ccc}},
    // 这个属性描述了一个客户端特征配置描述符，UUID 为 `character_client_config_uuid`
    // 该描述符具有读写权限，大小为 2 字节，存储在 `heart_measurement_ccc` 中
    // 该描述符用于控制通知和指示的启用/禁用
};


void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
    switch (event) {
        case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT: {
            if (param->ext_adv_set_params.status != ESP_BT_STATUS_SUCCESS) {
                ESP_LOGE(BLE_TAG, "set ext adv params failed, status %d", param->ext_adv_set_params.status);
                break;
            }

            adv_config_done = 0;

            esp_err_t ret = esp_ble_gap_config_ext_adv_data_raw(
                BLE_EXT_ADV_HANDLE,
                sizeof(raw_adv_data),
                raw_adv_data);
            if (ret) {
                ESP_LOGE(BLE_TAG, "config ext adv data failed: %s", esp_err_to_name(ret));
            } else {
                adv_config_done |= ADV_CONFIG_FLAG;
            }

            ret = esp_ble_gap_config_ext_scan_rsp_data_raw(
                BLE_EXT_ADV_HANDLE,
                sizeof(raw_scan_rsp_data),
                raw_scan_rsp_data);
            if (ret) {
                ESP_LOGE(BLE_TAG, "config ext scan rsp data failed: %s", esp_err_to_name(ret));
            } else {
                adv_config_done |= SCAN_RSP_CONFIG_FLAG;
            }

            start_ext_advertising();
            break;
        }

        case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT:
            if (param->ext_adv_data_set.status != ESP_BT_STATUS_SUCCESS) {
                ESP_LOGE(BLE_TAG, "ext adv data set failed, status %d", param->ext_adv_data_set.status);
            } else {
                adv_config_done &= (~ADV_CONFIG_FLAG);
                start_ext_advertising();
            }
            break;

        case ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT:
            if (param->scan_rsp_set.status != ESP_BT_STATUS_SUCCESS) {
                ESP_LOGE(BLE_TAG, "ext scan rsp data set failed, status %d", param->scan_rsp_set.status);
            } else {
                adv_config_done &= (~SCAN_RSP_CONFIG_FLAG);
                start_ext_advertising();
            }
            break;

        case ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT:
            if (param->ext_adv_start.status != ESP_BT_STATUS_SUCCESS) {
                ESP_LOGE(BLE_TAG, "ext advertising start failed, status %d", param->ext_adv_start.status);
            } else {
                ESP_LOGI(BLE_TAG, "ext advertising started");
            }
            break;

        case ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT:
            if (param->ext_adv_stop.status != ESP_BT_STATUS_SUCCESS) {
                ESP_LOGE(BLE_TAG, "ext advertising stop failed, status %d", param->ext_adv_stop.status);
            } else {
                ESP_LOGI(BLE_TAG, "ext advertising stopped");
            }
            break;

        case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
            ESP_LOGI(BLE_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
                  param->update_conn_params.status,
                  param->update_conn_params.min_int,
                  param->update_conn_params.max_int,
                  param->update_conn_params.conn_int,
                  param->update_conn_params.latency,
                  param->update_conn_params.timeout);
            break;

        default:
            break;
    }
}

//暂时用不到
void example_prepare_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
{
    ESP_LOGI(BLE_TAG, "prepare write, handle = %d, value len = %d", param->write.handle, param->write.len);
    esp_gatt_status_t status = ESP_GATT_OK;
    if (param->write.offset > PREPARE_BUF_MAX_SIZE) {
        status = ESP_GATT_INVALID_OFFSET;
    } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) {
        status = ESP_GATT_INVALID_ATTR_LEN;
    }
    if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) {
        prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t));
        prepare_write_env->prepare_len = 0;
        if (prepare_write_env->prepare_buf == NULL) {
            ESP_LOGE(BLE_TAG, "%s, Gatt_server prep no mem", __func__);
            status = ESP_GATT_NO_RESOURCES;
        }
    }

    /*send response when param->write.need_rsp is true */
    if (param->write.need_rsp){
        esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t));
        if (gatt_rsp != NULL){
            gatt_rsp->attr_value.len = param->write.len;
            gatt_rsp->attr_value.handle = param->write.handle;
            gatt_rsp->attr_value.offset = param->write.offset;
            gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
            memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
            esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp);
            if (response_err != ESP_OK) {
               ESP_LOGE(BLE_TAG, "Send response error");
            }
            free(gatt_rsp);
        }else{
            ESP_LOGE(BLE_TAG, "%s, malloc failed", __func__);
            status = ESP_GATT_NO_RESOURCES;
        }
    }
    if (status != ESP_GATT_OK){
        return;
    }
    memcpy(prepare_write_env->prepare_buf + param->write.offset,
           param->write.value,
           param->write.len);
    prepare_write_env->prepare_len += param->write.len;

}
//暂时用不到
void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param){
    if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC && prepare_write_env->prepare_buf){
        esp_log_buffer_hex(BLE_TAG, prepare_write_env->prepare_buf, prepare_write_env->prepare_len);
    }else{
        ESP_LOGI(BLE_TAG,"ESP_GATT_PREP_WRITE_CANCEL");
    }
    if (prepare_write_env->prepare_buf) {
        free(prepare_write_env->prepare_buf);
        prepare_write_env->prepare_buf = NULL;
    }
    prepare_write_env->prepare_len = 0;
}



// GATT 服务器事件处理函数
// 用于处理与 GATT 服务器相关的各类事件，如连接、读写操作等
void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
    switch (event) {
        // 处理注册事件，ESP_GATTS_REG_EVT
        case ESP_GATTS_REG_EVT:{
            esp_err_t set_dev_name_ret = esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME);
            if (set_dev_name_ret){
                ESP_LOGE(BLE_TAG, "set device name failed, error code = %x", set_dev_name_ret);
            }

            esp_err_t ext_adv_ret = esp_ble_gap_ext_adv_set_params(BLE_EXT_ADV_HANDLE, &ext_adv_params);
            if (ext_adv_ret){
                ESP_LOGE(BLE_TAG, "set ext adv params failed, error code = %x", ext_adv_ret);
            }

            esp_err_t create_attr_ret = esp_ble_gatts_create_attr_tab(gatt_db, gatts_if, HRS_IDX_NB, SVC_INST_ID);
            if (create_attr_ret){
                ESP_LOGE(BLE_TAG, "create attr table failed, error code = %x", create_attr_ret);
            }
        }
        break;

        // 处理读取事件，ESP_GATTS_READ_EVT
        case ESP_GATTS_READ_EVT:
            ESP_LOGI(BLE_TAG, "ESP_GATTS_READ_EVT");
        break;

        // 处理写入事件，ESP_GATTS_WRITE_EVT
        case ESP_GATTS_WRITE_EVT:
            // 如果不是预备写事件
            if (!param->write.is_prep){
                // 输出写入操作的详细信息
                ESP_LOGI(BLE_TAG, "GATT_WRITE_EVT, handle = %d, value len = %d, value :", param->write.handle, param->write.len);
                esp_log_buffer_hex(BLE_TAG, param->write.value, param->write.len);

                // 判断数据内容，如果数据长度大于等于5，并且首位为0xFF，尾位为0xFE
                if (param->write.len>=5){
                    if (param->write.value[0]==0xFF && param->write.value[param->write.len-1]==0xFE){
                        //send_count=0;  // 重置发送计数
                        //notify_flag=true;  // 启用通知标志
                    }
                }

                // 检查是否是手柄服务配置的特征值
                if (heart_rate_handle_table[IDX_CHAR_CFG_A] == param->write.handle && param->write.len == 2){
                    uint16_t descr_value = param->write.value[1]<<8 | param->write.value[0];

                    // 开启通知
                    if (descr_value == 0x0001){
                        ESP_LOGI(BLE_TAG, "notify enable");
                        //send_count=0;
                        //notify_flag=true;
                    }
                    // 开启指示
                    else if (descr_value == 0x0002){
                        ESP_LOGI(BLE_TAG, "indicate enable");
                        uint8_t indicate_data[15];
                        for (int i = 0; i < sizeof(indicate_data); ++i)
                        {
                            indicate_data[i] = i % 0xff;
                        }
                        // 发送指示
                        esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, heart_rate_handle_table[IDX_CHAR_VAL_A],
                                            sizeof(indicate_data), indicate_data, true);
                    }
                    // 关闭通知/指示
                    else if (descr_value == 0x0000){
                        ESP_LOGI(BLE_TAG, "notify/indicate disable ");
                        // notify_flag=false;
                    }else{
                        ESP_LOGE(BLE_TAG, "unknown descr value");
                        esp_log_buffer_hex(BLE_TAG, param->write.value, param->write.len);
                    }
                }

                // 如果需要响应写操作，发送响应
                if (param->write.need_rsp){
                    esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
                }
            }
            else {
                // 处理预备写事件
                example_prepare_write_event_env(gatts_if, &prepare_write_env, param);
            }
        break;

        // 处理执行写操作事件，ESP_GATTS_EXEC_WRITE_EVT
        case ESP_GATTS_EXEC_WRITE_EVT:
            ESP_LOGI(BLE_TAG, "ESP_GATTS_EXEC_WRITE_EVT");
            example_exec_write_event_env(&prepare_write_env, param);
        break;

        // 处理 MTU 设置事件，ESP_GATTS_MTU_EVT
        case ESP_GATTS_MTU_EVT:
            ESP_LOGI(BLE_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
        break;

        // 处理确认事件，ESP_GATTS_CONF_EVT
        case ESP_GATTS_CONF_EVT:
            //ESP_LOGI(BLE_TAG, "ESP_GATTS_CONF_EVT, status = %d, attr_handle %d", param->conf.status, param->conf.handle);
        break;

        // 处理服务启动事件，ESP_GATTS_START_EVT
        case ESP_GATTS_START_EVT:
            ESP_LOGI(BLE_TAG, "SERVICE_START_EVT, status %d, service_handle %d", param->start.status, param->start.service_handle);
        break;

        // 处理连接事件，ESP_GATTS_CONNECT_EVT
        case ESP_GATTS_CONNECT_EVT:
            ESP_LOGI(BLE_TAG, "ESP_GATTS_CONNECT_EVT, conn_id = %d", param->connect.conn_id);
            esp_log_buffer_hex(BLE_TAG, param->connect.remote_bda, 6);

            // 更新连接参数
            esp_ble_conn_update_params_t conn_params = {0};
            memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
            conn_params.latency = 0;
            conn_params.max_int = 0x20;    // max_int = 0x20*1.25ms = 40ms
            conn_params.min_int = 0x10;    // min_int = 0x10*1.25ms = 20ms
            conn_params.timeout = 400;     // timeout = 400*10ms = 4000ms
            esp_ble_gap_update_conn_params(&conn_params);
            connected=1;
        break;

        // 处理断开连接事件，ESP_GATTS_DISCONNECT_EVT
        case ESP_GATTS_DISCONNECT_EVT:
            ESP_LOGI(BLE_TAG, "ESP_GATTS_DISCONNECT_EVT, reason = 0x%x", param->disconnect.reason);
            // 重新开始广告
            start_ext_advertising();
            connected=0;
        break;

        // 处理创建属性表事件，ESP_GATTS_CREAT_ATTR_TAB_EVT
        case ESP_GATTS_CREAT_ATTR_TAB_EVT:{
            if (param->add_attr_tab.status != ESP_GATT_OK){
                ESP_LOGE(BLE_TAG, "create attribute table failed, error code=0x%x", param->add_attr_tab.status);
            }
            else if (param->add_attr_tab.num_handle != HRS_IDX_NB){
                ESP_LOGE(BLE_TAG, "create attribute table abnormally, num_handle (%d) \
                        doesn't equal to HRS_IDX_NB(%d)", param->add_attr_tab.num_handle, HRS_IDX_NB);
            }
            else {
                ESP_LOGI(BLE_TAG, "create attribute table successfully, the number handle = %d", param->add_attr_tab.num_handle);
                memcpy(heart_rate_handle_table, param->add_attr_tab.handles, sizeof(heart_rate_handle_table));
                esp_ble_gatts_start_service(heart_rate_handle_table[IDX_SVC]);
            }
            break;
        }

        // 默认事件
        case ESP_GATTS_STOP_EVT:
        case ESP_GATTS_OPEN_EVT:
        case ESP_GATTS_CANCEL_OPEN_EVT:
        case ESP_GATTS_CLOSE_EVT:
        case ESP_GATTS_LISTEN_EVT:
        case ESP_GATTS_CONGEST_EVT:
        case ESP_GATTS_UNREG_EVT:
        case ESP_GATTS_DELETE_EVT:
        default:
            break;
    }
}

// GATT 事件处理回调函数
// 该函数用于处理来自 GATT 服务器的各种事件
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
    // 如果事件是注册事件（ESP_GATTS_REG_EVT），即应用程序初始化时的注册过程
    if (event == ESP_GATTS_REG_EVT) {
        // 检查应用程序是否注册成功
        if (param->reg.status == ESP_GATT_OK) {
            // 如果注册成功，保存对应的 gatts_if（GATT 接口）到配置文件中
            heart_rate_profile_tab[PROFILE_APP_IDX].gatts_if = gatts_if;
        } else {
            // 如果注册失败，打印错误信息，包括应用程序 ID 和状态码
            ESP_LOGE(BLE_TAG, "reg app failed, app_id %04x, status %d",
                    param->reg.app_id,
                    param->reg.status);
            return;  // 注册失败，直接返回
        }
    }

    do {
        int idx;
        // 遍历所有的配置文件（PROFILE_NUM 是配置文件数量的常量）
        for (idx = 0; idx < PROFILE_NUM; idx++) {
            /* ESP_GATT_IF_NONE：表示没有指定特定的 gatt_if，需要调用每个配置文件的回调函数 */
            if (gatts_if == ESP_GATT_IF_NONE || gatts_if == heart_rate_profile_tab[idx].gatts_if) {
                // 如果该配置文件有注册回调函数，则调用回调函数处理事件
                if (heart_rate_profile_tab[idx].gatts_cb) {
                    // 调用指定的回调函数，传入事件类型、GATT 接口、参数
                    heart_rate_profile_tab[idx].gatts_cb(event, gatts_if, param);
                }
            }
        }
    } while (0); 
}


void ble_init(){
    // 初始化蓝牙控制器配置，使用默认配置
    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();

    // 初始化蓝牙控制器，传入配置结构体
    esp_err_t ret = esp_bt_controller_init(&bt_cfg);
    if (ret) {
        // 如果初始化失败，打印错误信息并返回
        ESP_LOGE(BLE_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
        return;
    }

    // 启动蓝牙控制器，设置为 BLE 模式
    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
    if (ret) {
        // 如果启动失败，打印错误信息并返回
        ESP_LOGE(BLE_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
        return;
    }

    // 初始化蓝牙堆栈（Bluedroid）
    ret = esp_bluedroid_init();
    if (ret) {
        // 如果初始化失败，打印错误信息并返回
        ESP_LOGE(BLE_TAG, "%s init bluetooth failed: %s", __func__, esp_err_to_name(ret));
        return;
    }

    // 启动蓝牙堆栈（Bluedroid）
    ret = esp_bluedroid_enable();
    if (ret) {
        // 如果启用失败，打印错误信息并返回
        ESP_LOGE(BLE_TAG, "%s enable bluetooth failed: %s", __func__, esp_err_to_name(ret));
        return;
    }

    // 注册 GATT 服务事件回调函数
    ret = esp_ble_gatts_register_callback(gatts_event_handler);
    if (ret) {
        // 如果注册失败，打印错误信息并返回
        ESP_LOGE(BLE_TAG, "gatts register error, error code = %x", ret);
        return;
    }

    // 注册 GAP（蓝牙设备间通信）事件回调函数
    ret = esp_ble_gap_register_callback(gap_event_handler);
    if (ret) {
        // 如果注册失败，打印错误信息并返回
        ESP_LOGE(BLE_TAG, "gap register error, error code = %x", ret);
        return;
    }

    // 注册 GATT 应用程序，指定应用程序 ID
    ret = esp_ble_gatts_app_register(ESP_APP_ID);
    if (ret) {
        // 如果注册失败，打印错误信息并返回
        ESP_LOGE(BLE_TAG, "gatts app register error, error code = %x", ret);
        return;
    }

    // 设置本地设备的最大传输单元（MTU）为500字节
    esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500);
    if (local_mtu_ret) {
        // 如果设置失败，打印错误信息
        ESP_LOGE(BLE_TAG, "set local MTU failed, error code = %x", local_mtu_ret);
    }
}
